package org.example.nt.gm;

import cn.gmssl.jce.provider.GMJCE;
import cn.gmssl.jsse.provider.GMJSSE;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.CharsetUtil;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

import static cn.gmssl.jsse.provider.GMJSSE.GMSSLv11;

public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {

    private static final Provider GMJCE = new GMJCE();

    private static final Provider GMSSE = new GMJSSE();

    static {
        Security.insertProviderAt(GMJCE, 1);
        Security.insertProviderAt(GMSSE, 1);
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast(createSslHandler(initSSLContext(), false));
        // 编解码
        socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast(new NettyServerHandler());
    }

    private ChannelHandler createSslHandler(SSLContext sslContext, boolean needsClientAuth) {
        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setUseClientMode(false);
        if (needsClientAuth) {
            sslEngine.setNeedClientAuth(true);
        }
        return new SslHandler(sslEngine);
    }

    private SSLContext initSSLContext() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
        try {
            SSLContext sslContext = SSLContext.getInstance(GMJSSE.GMSSLv11, GMJSSE.NAME);
            KeyStore pfx = KeyStore.getInstance("PKCS12", "GMJSSE");
            String pfxfile =  "D:/ws/java/springboot-demo/netty-demo/keystore/sm2.server1.both.pfx";
            String pwdpwd = "12345678";
            pfx.load(new FileInputStream(pfxfile), pwdpwd.toCharArray());
//            KeyManagerFactory kmf = KeyManagerFactory.getInstance("CM");
//            kmf.init(pfx, pwdpwd.toCharArray());

            sslContext.init(null, null, null);
            return sslContext;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
